package com.internetCafes.spms.common.aspect;

import com.internetCafes.spms.common.CommonConstants;
import com.internetCafes.spms.common.utils.ShiroUtils;
import com.internetCafes.spms.core.annotation.DataFilter;
import com.internetCafes.spms.core.annotation.NoSQLFilter;
import com.internetCafes.spms.core.exception.RRException;
import com.internetCafes.spms.web.sys.model.UserInfo;
import com.internetCafes.spms.web.sys.service.DeptInfoService;
import com.internetCafes.spms.web.sys.service.RoleDeptInfoService;
import com.internetCafes.spms.web.sys.service.UserRoleInfoService;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * 数据过滤，切面处理类
 * @author Sunny
 * @email rekeeper2011@hotmail.com
 * @date 2017/9/17 15:02
 */
@Aspect
@Component
public class NoSQLFilterAspect {

    @Autowired
    private UserRoleInfoService userRoleInfoService;

    @Autowired
    private RoleDeptInfoService roleDeptInfoService;



    @Pointcut("@annotation(com.internetCafes.spms.core.annotation.NoSQLFilter)")
    public void dataFilterCut() {

    }



    @Before("dataFilterCut()")
    public void dataFilter(JoinPoint point) throws Throwable {
        Object params = point.getArgs()[2];
        if(params != null && params instanceof Query){
            UserInfo user = ShiroUtils.getUserEntity();
            //如果不是超级管理员，则只能查询本部门及子部门数据
            if(user.getId() != CommonConstants.SUPER_ADMIN){
                getFilterSQL(user, point, (Query)params);
            }
            return;
        }
        throw new RRException("要实现数据权限接口的参数，只能是Query类型，且不能为NULL");
    }



    /**
     * 获取数据过滤的SQL
     */
    private void getFilterSQL(UserInfo user, JoinPoint point, Query query){
        MethodSignature signature = (MethodSignature) point.getSignature();
        NoSQLFilter d = signature.getMethod().getAnnotation(NoSQLFilter.class);

        List<Long> resultDeptIds = new ArrayList<>();
        List<Long> roleIds = userRoleInfoService.queryRoleIdList(user.getId());
        if(roleIds != null && roleIds.size() > 0){
            List<Long> deptIds;
            if(roleIds.size() == 1){
                deptIds = roleDeptInfoService.queryDeptIdList(roleIds.get(0));
                if(deptIds != null && deptIds.size() > 0){
                    resultDeptIds.addAll(deptIds);
                }
            } else {
                deptIds = roleDeptInfoService.queryDeptIdList(roleIds.get(0));
                if(deptIds != null && deptIds.size() > 0){
                    resultDeptIds.addAll(deptIds);
                }
                for(int i=1; i < roleIds.size(); i++){
                    deptIds = roleDeptInfoService.queryDeptIdList(roleIds.get(i));
                    if(deptIds != null && deptIds.size() > 0){
                        for(Long deptId:deptIds){
                            if(!resultDeptIds.contains(deptId)){
                                resultDeptIds.add(deptId);
                            }
                        }
                    }
                }
            }
        }


        if(resultDeptIds.size() == 0 && !d.user()){
            return;
        } else if(resultDeptIds.size() > 0 && d.user()){
            Criteria c = new Criteria();
            Pattern pattern = Pattern.compile("^.*"+user.getId()+".*$", Pattern.CASE_INSENSITIVE);
            c.orOperator(Criteria.where("deptId").in(resultDeptIds),Criteria.where("createBy").is(user.getId()), Criteria.where("ccIds").regex(pattern));
            query.addCriteria(c);
        } else {
            if(resultDeptIds.size() > 0) {
                query.addCriteria(Criteria.where("deptId").in(resultDeptIds));
            }

            if(d.user()){
                query.addCriteria(Criteria.where("createBy").is(user.getId()));
            }
        }
    }
}
